﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Globalization;
using System.Web;
using System.Web.UI.WebControls;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Utilities;
using Microsoft.SharePoint.WebControls;
using TemplateLibraryConnector.Data;
using TemplateLibraryConnector.Utility;
using TemplateLibraryConnector.UI;


namespace TemplateLibraryConnector
{
    public partial class Selector : ViewStateEnabledLayoutsPage
    {

        #region properties

        private const string PreviewImageUrlPrefix = "/_layouts/15/TemplateLibraryConnector/thumbnail.ashx?";
        private string _fileName;
        private readonly List<string> _items = new List<string>();
        public static string FileName { get; set; }
        public static string FileTitle { get; set; }
        public static string FileUrl { get; set; }

        /// <summary>
        /// set or get the Current Page Number
        /// </summary>
        public int CurrentPage
        {
            get
            {
                //get current page number
                object obj = ViewState["_CurrentPage"];
                if (obj == null)
                {
                    return 0;
                }
                
                return (int)obj;
            }
            set
            {
                //set in viewstate the current page number
                ViewState["_CurrentPage"] = value;
            }
        }



        public PagedDataSource PagedDataSource = new PagedDataSource();
        
        [PersistToViewState]
        public string DestinationLibraryUrl { get; set; }

        [PersistToViewState]
        public string TemplateHubAddress { get; set; }

        [PersistToViewState]
        public string TemplateLibraryAddress { get; set; }

        [PersistToViewState]
        public TemplateViewType TemplateViewType { get; set; }

        
        #endregion

        #region load events

        protected override void OnPreRender(EventArgs e)
        {
            CssRegistration.Register("/_layouts/15/TemplateLibraryConnector/Styles/TemplateHub.css");

            PopulateViewAndDataSource();

            if (pnlThumbNail.Visible)
            {
                spDataList.DataBind();
                BindPager();
            }
            else
            {
                spDetailView.DataBind();
            }
        }

        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);

            try
            {
                if (!Page.IsPostBack)
                {
                    spDetailView.SelectedIndex = -1;
                    BtnCreate.Enabled = false;
                    FavButton.Enabled = false;
                    SwitchToThumbViewBtn.Enabled = false;
                    AddTopMenuSelectedClass(SwitchToThumbViewBtn);

                    Uri destonationUrl;
                    if (Request.QueryString["Referer"] != null)
                    {
                        destonationUrl = new Uri(Request.QueryString["Referer"]);
                    }
                    else
                    {
                        destonationUrl = Request.UrlReferrer;
                    }
                    
                    DestinationLibraryUrl = TemplateLibraryDataUtility.GetLibraryUrl(destonationUrl.AbsoluteUri);

                    using (var site = TemplateLibraryDataUtility.GetDocumentLibrarySite(destonationUrl.AbsoluteUri))
                    {
                        using (var web = site.OpenWeb())
                        {

                            if (Request.QueryString["listId"] != null)
                            {
                                string listId = Request.QueryString["listId"].ToString();

                                var destinationLibrary = web.Lists[new Guid(listId)] as SPDocumentLibrary;
                                var destinationLibraryServerRelativeURL = destinationLibrary.RootFolder.ServerRelativeUrl;
                                this.DestinationLibraryUrl = site.MakeFullUrl(destinationLibrary.RootFolder.ServerRelativeUrl);

                                var settings = TemplateLibrarySettings.LoadFromList(destinationLibrary);

                                if (settings == null)
                                {
                                    var settingsUrl = string.Format("TemplateLibraryConnector/TemplateLibraryConnectorConfig.aspx?IsDlg=1&List={0}&Referer={1}&DestinationList={2}", destinationLibrary.ID, SPUtility.GetPageUrlPath(HttpContext.Current), DestinationLibraryUrl);
                                    SPUtility.Redirect(settingsUrl, SPRedirectFlags.RelativeToLayoutsPage, HttpContext.Current);
                                    return;
                                }

                                ToggleVisibleGrid(GridType.ThumbnailView);
                                FavButton.ImageUrl = "~/_layouts/15/Images/ADDTOFAVORITES.GIF";
                                TemplateViewType = TemplateViewType.All;
                            }
                        }
                    }
                    

                    AddMenuSelectedClass(MenuAllTemplates);
                }

                lblConfirmationMessage.Visible = false;
                viewSelector.SelectedViewChanged += ViewSelectorSelectedViewChanged;

                //wiring of singleclick on datalist not working. Call manually
                if (Request.Form["__EVENTTARGET"] != null && Request.Form["__EVENTTARGET"].Contains("spDataList$ctl") && Request.Form["__EVENTTARGET"].EndsWith("ctl00"))
                {
                    DataListItemCommand(spDataList, null);
                }
            }
            catch (Exception ex)
            {
                ULSLogger.LogError("Error Occured", ex);
            }

        }

        protected override void CreateChildControls()
        {
            base.CreateChildControls();
            PopulateViewAndDataSource();
        }


        #endregion


        private void PopulateViewAndDataSource() 
        {
            var templateHubController = new TemplateHubController(DestinationLibraryUrl);

            //Pick which template to pass here
            if (pnlThumbNail.Visible)
            {
                PagedDataSource.AllowPaging = true;
                PagedDataSource.PageSize = 12;
                PagedDataSource.CurrentPageIndex = CurrentPage;
                templateHubController.PopulateDataSource(TemplateViewType, spDataList, txtSearch.Text, viewSelector.SelectedViewId, PagedDataSource);
            }
            else
            {
                spDetailView.AutoGenerateSelectButton = false;
                spDetailView.EnableViewState = true;
                spDetailView.AllowSorting = true;
                spDetailView.AllowFiltering = true;
                spDetailView.AllowPaging = true;
                spDetailView.PageSize = 12;
                spDetailView.AutoGenerateColumns = false;

                templateHubController.PopulateDataSource(TemplateViewType, spDetailView, txtSearch.Text, viewSelector.SelectedViewId, null);
            }

          
        }

        private void ViewSelectorSelectedViewChanged(object sender, EventArgs e)
        {
            ResetPage(false);
        }

        
        private void BindPager()
        {
            if (spDataList.Items.Count == 0)
            {
                NoItemsSelectedLiteral.Visible = true;
                btnNext.Visible = false;
                btnPrevious.Visible = false;
                ltrCurrentItems.Visible = false;
            }
            else
            {

                NoItemsSelectedLiteral.Visible = false;
                btnNext.Visible = !PagedDataSource.IsLastPage;
                btnPrevious.Visible = !PagedDataSource.IsFirstPage;
                ltrCurrentItems.Visible = !(PagedDataSource.IsLastPage && PagedDataSource.IsFirstPage);
                ltrCurrentItems.Text = (PagedDataSource.FirstIndexInPage + 1).ToString(CultureInfo.InvariantCulture) + "-";
                if (PagedDataSource.DataSourceCount > PagedDataSource.FirstIndexInPage + PagedDataSource.PageSize)
                    ltrCurrentItems.Text = ltrCurrentItems.Text + (PagedDataSource.FirstIndexInPage + PagedDataSource.PageSize).ToString(CultureInfo.InvariantCulture);
                else
                    ltrCurrentItems.Text = ltrCurrentItems.Text + PagedDataSource.DataSourceCount.ToString(CultureInfo.InvariantCulture);
            }
 
        }

        
        
#region rowEvents

        protected void DetailViewRowDataBound(object sender, GridViewRowEventArgs e)
        {
            if (e.Row.RowType == DataControlRowType.Header)
            {
                e.Row.Cells.AddAt(0, new TableHeaderCell { Text = "", CssClass = "ms-vh2-nofilter ms-vh2-gridview" });
                return;
            }
            if (e.Row.RowType == DataControlRowType.DataRow)
            {
                var currentItem = (DataRowView)e.Row.DataItem;

                e.Row.Cells.AddAt(0, new TableCell{Text = string.Format("<img src=\"/_layouts/15/images/{0}\" />", SPUtility.MapToIcon(SPContext.Current.Web, currentItem["FileLeafRef"].ToString(), "0"))});
                e.Row.Attributes["onclick"] = ClientScript.GetPostBackClientHyperlink(spDetailView, "Select$" + e.Row.RowIndex);
                e.Row.Attributes.Add("ondblclick", OnItemDoubleClick(currentItem));

                _items.Add(currentItem["FileLeafRef"].ToString());
                
            }

            ViewState["_items"] = _items;
        }

        protected void DataListItemDataBound(object sender, DataListItemEventArgs e)
        {
            if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
            {
                // Get the first LinkButton control
                var singleClickButton = (LinkButton)e.Item.Controls[0];
                // Get the javascript which is assigned to this LinkButton
                var jsSingle = ClientScript.GetPostBackClientHyperlink(singleClickButton, "");
                // To prevent the first click from posting back immediately 
                // (therefore giving the user a chance to double click) pause the 
                // postback for 300 milliseconds by using setTimeout
                jsSingle = jsSingle.Insert(11, "setTimeout(\"");
                jsSingle += "\", 300)";
                
                // Get the panel wrapping the item
                var itemPanel = (Panel)e.Item.Controls[2];
                // Add this javascript to the onclick Attribute of the panel
                itemPanel.Attributes["onclick"] = jsSingle;

                // Get the javascript which is assigned to this LinkButton
                var currentItem = (DataRowView)e.Item.DataItem;
                
                var jsDouble = OnItemDoubleClick(currentItem);
                // Add this javascript to the ondblclick Attribute of the panel
                itemPanel.Attributes["ondblclick"] = jsDouble;   
            }
        }


        protected string OnItemDoubleClick(DataRowView item)
        {
            //_fileName = item["EncodedAbsUrl"].ToString();
            _fileName = item["FileLeafRef"].ToString();
           
            var sitecollection = SPContext.Current.Site.Url;

            if( string.IsNullOrEmpty(DestinationLibraryUrl))
                DestinationLibraryUrl = TemplateLibraryDataUtility.GetLibraryUrl(Request.UrlReferrer.AbsoluteUri);
            
            //Get current published version
            var fileversionUrl = TemplateHubController.GetFileVersion(_fileName);

            var navigateUrl = string.Format("javascript:window.location.href = '{0}/_layouts/15/TemplateLibraryConnector/LastUsed.ashx?Name={1}';",
                   sitecollection, Server.UrlEncode(fileversionUrl));
             navigateUrl += TemplateHubController.CreateTemplate(fileversionUrl, DestinationLibraryUrl); 

            return navigateUrl;
        }

        
        #endregion
        #region SelectedIndexchanged

        protected void DetailViewSelectedIndexChanged(object sender, EventArgs e)
        {
            var s = sender as ServerControls.SPGridViewMultiSortFilter;
            
            if (s != null)
            {
                if (s.SelectedDataKey != null)
                {
                    var selectedItemId = Convert.ToInt32(s.SelectedDataKey.Value);
                    PerformItemCommand(selectedItemId);
                }
            }

            PopulateViewAndDataSource();
        }


        private void PerformItemCommand(int selectedItemId)
        {
            BtnCreate.Enabled = true;
            FavButton.Enabled = true;
            
            var templateHubController = new TemplateHubController(DestinationLibraryUrl);

            var templateHubUrl = templateHubController._settings.GetTemplateHubAddress(string.Empty);
            var listId = new Guid(templateHubController._settings.TemplateListIds);
            using (var templateHubSite = TemplateLibraryDataUtility.GetDocumentLibrarySite(templateHubUrl))
            {
                using (var templateHubWeb = TemplateLibraryDataUtility.GetDocumentLibraryWebFromUrl(templateHubUrl, templateHubSite))
                {
                    var docLib = templateHubWeb.Lists[listId] as SPDocumentLibrary;

                    if (docLib != null)
                    {
                        var item = docLib.GetItemById(selectedItemId);

                        SelectImage(item);
                        GetFileInfo(item);
                        DisplayMetaData(item);
                    }
                }
            }

            FavButton.ImageUrl = TemplateHubController.DoILikeThis(FileUrl).ToString();
        }

        private void GetFileInfo(SPListItem item)
        {
            
            FileName = item.File.Name;
            FileTitle = item.File.Title;
            FileUrl = item.File.Url;
        }

        protected void DataListItemCommand(object sender, DataListCommandEventArgs e)
        {
            var s = sender as DataList;

            if (s != null)
            {
                //population in createchildcontrols has wrong paramenters, repopulate
                var templateHubController = new TemplateHubController(DestinationLibraryUrl);
                templateHubController.PopulateDataSource(TemplateViewType, spDataList, txtSearch.Text, viewSelector.SelectedViewId, PagedDataSource);
                var pagedDataSource = s.DataSource as PagedDataSource;
                var listItems = pagedDataSource.DataSource as DataView;

                var target = Request.Form["__EVENTTARGET"];

                s.SelectedIndex = Convert.ToInt32(target.Substring(target.IndexOf("spDataList") + 14, 2));
                var index = s.SelectedIndex + (PagedDataSource.PageSize * CurrentPage);

                PerformItemCommand(Convert.ToInt32(listItems[index]["ID"]));

            }
        }

        #endregion

        #region DisplayPreviewAndMetadata

        private void SelectImage(SPListItem s)
        {
            PreviewImage.Visible = true;
            PreviewImage.ImageUrl = TemplateHubController.GetThumbNail(PreviewImageUrlPrefix, s.File.Name) + "&width=200";
        }

        private void DisplayMetaData(SPListItem item)
        {
            PreviewImageText.Visible = false;
            var props = TemplateHubController.GetMetaData(item);
            foreach (var entry in props)
            {
                if( entry.Value.Split('|').Length == 2)
                {
                    var entryName = entry.Value.Split('|')[0];
                    var entryValue = entry.Value.Split('|')[1];

                    switch (entry.Key.ToLower())
                    {
                        case "title":
                            TemplateTitle.Text = entryValue;
                            break;
                        default:
                            if (entry.Key.ToLower() == ("template_x0020_title") || (entry.Key.ToLower().Contains("template") && entry.Key.ToLower().Contains("title")))
                                TemplateTitle.Text = entryValue;
                            else
                                PreviewPanel.ContentTemplateContainer.Controls.Add(new Label { Text = "<b>" + entryName + ":</b> " + entryValue, CssClass = "MetaDataLabel" });
                            break;
                    }
                    }
                
            }
        }

        #endregion

        #region buttonevents

        protected void CreateButtonClick(object sender, EventArgs e)
        {
            var currentuser = SPContext.Current.Web.CurrentUser.LoginName;
            var sitecollection = SPContext.Current.Site.ID;
            
            var fileversionUrl = TemplateHubController.GetFileVersion(FileName);
           
            TemplateHubController.UpdateLastUsedProperty(FileName, currentuser, sitecollection);
            var navigateUrl = TemplateHubController.CreateTemplate(SPHttpUtility.HtmlEncode(fileversionUrl), DestinationLibraryUrl);
            Response.Redirect(navigateUrl);

        }

        protected void SwitchToThumbViewBtn_OnClick(object sender, EventArgs e)
        {
            AddTopMenuSelectedClass(sender as ImageButton);

            ToggleVisibleGrid(GridType.ThumbnailView);
            SwitchToThumbViewBtn.Enabled = false;
            SwitchToListViewBtn.Enabled = true;

            ResetPage(false);
        }
        
        protected void SwitchToListViewBtn_OnClick(object sender, EventArgs e)
        {
            AddTopMenuSelectedClass(sender as ImageButton);

            ToggleVisibleGrid(GridType.ListView);
            SwitchToListViewBtn.Enabled = false;
            SwitchToThumbViewBtn.Enabled = true;
            ResetPage(false);
        }
        

        private void AddTopMenuSelectedClass(ImageButton selected)
        {
            SwitchToThumbViewBtn.CssClass = "";
            SwitchToListViewBtn.CssClass = "";
            selected.CssClass = "topNavbarSelected";
        }

        protected void SearchButtonOnClick(object sender, EventArgs e)
        {
            ResetPage(false);
        }

        #endregion


        private void ToggleVisibleGrid(GridType gt)
        {
            switch (gt)
            {
                case GridType.ListView:
                    {
                        pnlGridView.Visible = true;
                        pnlThumbNail.Visible = false;
                        SwitchToThumbViewBtn.Font.Bold = false;
                        SwitchToListViewBtn.Font.Bold = true;
                        break;
                    }
                case GridType.ThumbnailView:
                    {
                        pnlGridView.Visible = false;
                        pnlThumbNail.Visible = true;
                        SwitchToThumbViewBtn.Font.Bold = true;
                        SwitchToListViewBtn.Font.Bold = false;
                        break;
                    }
                default:
                    {
                        pnlGridView.Visible = true;
                        pnlThumbNail.Visible = false;
                        SwitchToThumbViewBtn.Font.Bold = false;
                        SwitchToListViewBtn.Font.Bold = true;
                        break;
                    }
            }
        }

        
        #region Pager

        protected void SpGridViewPagerOnClickNext(object sender, EventArgs e)
        {
            ResetPage(true);            
            
        }

        protected void SpGridViewPagerOnClickPrevious(object sender, EventArgs e)
        {
            ResetPage(true);
            
        }

        protected void PagerOnClickNext(object sender, EventArgs e)
        {

            CurrentPage += 1;
            ResetPage(true);

            PagedDataSource.CurrentPageIndex = CurrentPage;

        }

        protected void PagerOnClickPrevious(object sender, EventArgs e)
        {

            CurrentPage -= 1;
            ResetPage(true);

            PagedDataSource.CurrentPageIndex = CurrentPage;

        }


        #endregion

        protected void AllTemplates_OnClick(Object sender, EventArgs e)
        {
            AddMenuSelectedClass(sender as LinkButton);

            TemplateViewType = TemplateViewType.All;
            ResetPreviewPanel();
            ResetPage(false);

        }
        
        #region LastUsed

        protected void LastUsed_OnClick(Object sender, EventArgs e)
        {
            AddMenuSelectedClass( sender as LinkButton);
            TemplateViewType = TemplateViewType.LastUsed;
            ResetPreviewPanel();
            ResetPage(false);

        }

        #endregion

        #region favourites

        protected void Favorites_OnClick(object sender, EventArgs e)
        {
            AddMenuSelectedClass(sender as LinkButton);
            TemplateViewType = TemplateViewType.Favorites;
            ResetPreviewPanel();
            ResetPage(false);

            PagedDataSource.CurrentPageIndex = CurrentPage;
        }

        private void AddMenuSelectedClass(LinkButton selected)
        {
            MenuAllTemplates.CssClass = "";
            MenuLastUsed.CssClass = "";
            MenuFavorites.CssClass = "";
            selected.CssClass = "LeftMenuSelected";
        }

        private void ResetPreviewPanel()
        {
            TemplateTitle.Text = "";
            PreviewImage.Visible = false;
            PreviewImageText.Visible = true;
        }


        private void ResetPage(bool keepPager)
        {
            if (!keepPager)
            {
                CurrentPage = 0;
                spDetailView.PageIndex = 0;
            }
            PreviewImage.Visible = false;
            spDataList.SelectedIndex = -1;
            spDetailView.SelectedIndex = -1;
            BtnCreate.Enabled = false;
            FavButton.Enabled = false;
            FavButton.ImageUrl = "~/_layouts/15/Images/ADDTOFAVORITES.GIF";
        }
        
        protected void AddRemoveFavoriteBtnClick(object sender, EventArgs e )
        {
            if (FileName != null)
            {
                lblConfirmationMessage.Text = Language.GetString(TemplateHubController.AddOrRemoveFavorite(FileUrl, FileTitle) ? "TemplateAdded" : "TemplateRemoved");

                lblConfirmationMessage.Visible = true;
                
               FavButton.ImageUrl = TemplateHubController.DoILikeThis(FileUrl).ToString();
            }
        }

        #endregion
    }
}
